package com.cskaoyan.javase.oop1._10block._2building;

/**
 * @description: 构造代码块的总结
 * @author: wuguidong@cskaoyan.onaliyun.com
 **/

/**
 * > 总结一下到目前为止，创建对象过程中可能碰到的结构的执行顺序：
 *
 * new对象过程中，各种结构的执行顺序：
 * 1. 对象结构存在后就进行默认初始化，所有成员变量都具有默认值后，再开始其余赋值操作
 * 2. 找到new对象的那个构造器，
 *    - 如果它的首行显式地调用了另一个构造器
 *      （注：显式调用构造器可以使用this、super两个关键字，this已经学习，super后面学习）
 *      - 那么程序会先跳转到那个构造器，但是不会立刻执行，而是：
 *        - 按照类中构造代码块和显式赋值的代码书写顺序，从上到下执行其中的代码，执行完毕后：
 *      - 跳转回this或者super执行的构造器，执行完毕后：
 *      - 最终跳转回new对象构造器，执行完毕后，创建对象结束
 *    - 如果它的首行没有显式调用另一个构造器
 *      - 那么会先从上到下执行构造代码块和显式赋值代码，执行完毕后：
 *      - 跳转回new对象构造器，执行完毕后，创建对象结束
 * 3. 以上总结，没有引入继承的概念，并不全面，我们会在继承中补全它
 *
 * 构造代码块的实践用途:
 * > 根据构造代码块的特点，分析一下它的实际使用场景
 * 构造代码块最大的特点就是其中的代码会最终加入构造，所以依据这一点：
 * - 我们可以“提取公因式”一样的，把所有构造器都需要执行的代码，放入构造代码块中
 *
 * 其次，构造代码块毕竟是给成员变量赋值用的，所以：
 * - 如果需要很复杂的代码完成成员变量的赋值（如果只是给一个值，用显式赋值和构造器足矣）
 *   - 比如需要一个算法，需要一定计算等等
 *   - 这个场景下，使用构造代码块是一个不错的选择
 *
 *
 */
public class Demo2 {
    public static void main(String[] args) {
        Person p = new Person("马化腾", 38);
        System.out.println(p.age);
        System.out.println(p.name);
    }
}

class Person {
    {
        age = 28;
    }
    String name = "马云";
    int age = 48;
    {
        name = "东哥";
    }
    public Person(int age) {
        this.age = age;
    }

    public Person(String name, int age) {
        this(age);
        this.name = name;
    }
}